home *** CD-ROM | disk | FTP | other *** search
/ Power CD / Power CD ATARI-Rechner Lieben.iso / ALLERLEI / GOBJ_112 / UNITS / ODIALOGS.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-03-27  |  28.8 KB  |  1,063 lines

  1. {**************************************
  2.  *  O b j e c t G E M   Version 1.12  *
  3.  *  Copyright 1992-94 by Thomas Much  *
  4.  **************************************
  5.  *       Unit  O D I A L O G S        *
  6.  **************************************
  7.  *    Softdesign Computer Software    *
  8.  *    Thomas Much, Gerwigstraße 46,   *
  9.  *  76131 Karlsruhe, (0721) 62 28 41  *
  10.  *         Thomas Much @ KA2          *
  11.  *  UK48@ibm3090.rz.uni-karlsruhe.de  *
  12.  **************************************
  13.  *    erstellt am:        13.07.1992  *
  14.  *    letztes Update am:  27.03.1994  *
  15.  **************************************}
  16.  
  17. {
  18.   WICHTIGE ANMERKUNGEN ZUM QUELLTEXT:
  19.  
  20.   ObjectGEM wird ab sofort mit dem _vollständigen_ Quelltext ausgeliefert,
  21.   d.h. jeder kann sich die Unit selbst compilieren, womit die extrem
  22.   lästigen Kompatibilitätsprobleme mit den PP-Releases beseitigt sind.
  23.   ObjectGEM ist und bleibt aber trotzdem SHAREWARE, d.h. wer die Biblio-
  24.   thek regelmäßig benutzt, muß sich REGISTRIEREN lassen (so wie bisher).
  25.   Im Moment gibt es dafür dann "nur" die neueste Version; eine geTEXte
  26.   Doku ist aber in Arbeit, so daß auch ein gedrucktes Handbuch immer
  27.   wahrscheinlicher wird.
  28.  
  29.   Der Quelltext enthält z.Z. noch _keine_ Kommentare; wer sich dennoch die
  30.   Mühe macht, ihn zu lesen, wird feststellen, daß er außerdem noch recht
  31.   "wirr" und teilweise umständlich geschrieben ist, oder daß er evtl. auch
  32.   unnötige Teile enthält. Das liegt daran, daß dieser Quelltext eigentlich
  33.   gar nicht für eine Veröffentlichung gedacht war, aber immer häufiger auf-
  34.   tretende PP-Updates haben mich schier zur Verzweiflung getrieben...
  35.   Das alles sollte aber kein Grund sein, ObjectGEM nicht einzusetzen, denn
  36.   sobald nach "außen" die von mir gewünschte Funktionalität erreicht ist
  37.   (d.h. wenn alle wichtigen Objekte vorhanden sind, z.B. TEditWindow etc.),
  38.   werde ich mich um die "innere" Optimierung kümmern (dazu gehören dann
  39.   auch die Kommentare). Die bisher geschriebenen ObjectGEM-Anwendungen
  40.   können dann natürlich weiterverwendet werden.
  41.  
  42.   Wer beim Durchstöbern des Textes auf vermeintliche Fehler oder verbesse-
  43.   rungswürdige Stellen trifft (von letzterem gibt es sicherlich noch viele),
  44.   kann mir dies gerne mitteilen - ich habe auch ich nichts gegen kostenlos
  45.   zur Verfügung gestellte optimierte Routinen (sofern sich jemand die Mühe
  46.   macht). Wer in anderen Projekten, die nicht in direkter Konkurrenz zu
  47.   ObjectGEM stehen, einzelne Routinen verwenden möchte, wendet sich bitte
  48.   an mich (ein solcher Austausch sollte kein Problem sein).
  49.  
  50.   Wer sich auf nicht dokumentierte "implementation"- oder "private"-Eigen-
  51.   schaften verläßt, darf sich nicht über Inkompatibilitäten zu späteren
  52.   Versionen wundern; wer meint, eine Dokumentationslücke entdeckt zu haben
  53.   (außer dem "Abgrund" des noch fehlenden Handbuchs...), kann mir dies
  54.   gerne mitteilen.
  55.  
  56.   WICHTIG: Wer den Quelltext verändert und dann Probleme beim Compilieren,
  57.   Ausführen o.ä. hat, kann nicht damit rechnen, daß ich den Fehler suche;
  58.   tritt der Fehler allerdings auch mit dem Original-Quelltext auf, würde
  59.   ich mich über eine genaue Fehlerbeschreibung freuen. Veränderte Quell-
  60.   texte dürfen _nicht_ weitergegeben werden, dies wäre ein Verstoß gegen
  61.   das Copyright!
  62.  
  63.   Kleine Info zum Schluß: Als "default tabsize" verwende ich 2. Wer drei
  64.   Punkte ("...") im Quelltext entdeckt, hat eine Stelle gefunden, an der
  65.   ich z.Z. arbeite ;-)
  66.  
  67.   "Möge die OOP mit Euch sein!"
  68. }
  69.  
  70.  
  71. {$IFDEF DEBUG}
  72.     {$B+,D+,G-,I-,L+,N-,P-,Q+,R+,S+,T-,V-,X+,Z+}
  73. {$ELSE}
  74.     {$B+,D-,G-,I-,L-,N-,P-,Q-,R-,S-,T-,V-,X+,Z+}
  75. {$ENDIF}
  76.  
  77. unit ODialogs;
  78.  
  79. interface
  80.  
  81. uses
  82.  
  83.     Gem,OTypes,OWindows;
  84.  
  85. type
  86.  
  87.     PScrollBar = ^TScrollBar;
  88.     TScrollBar = object(TControl)
  89.         public
  90.         LineMagnitude,
  91.         PageMagnitude,
  92.         Size         : longint;
  93.         IsHorizontal : boolean;
  94.         constructor Init(AParent: PDialog; SIndx,DIndx,IIndx: integer; TheSize,TheRange: longint; Hlp: string);
  95.         function TestIndex(AnIndx: integer): boolean; virtual;
  96.         function Transfer(DataPtr: pointer; TransferFlag: word): word; virtual;
  97.         procedure Changed(AnIndx: integer; DblClick: boolean); virtual;
  98.         procedure Work; virtual;
  99.         procedure SetPosition(ThumbPos: longint); virtual;
  100.         function GetPosition: longint; virtual;
  101.         function DeltaPos(Delta: longint): longint; virtual;
  102.         procedure SetRange(LoVal,HiVal: longint); virtual;
  103.         function GetRange(var LoVal,HiVal: longint): longint; virtual;
  104.         function GetSBoxMin: integer; virtual;
  105.         private
  106.         lowval,
  107.         highval,
  108.         SPos,
  109.         Range   : longint;
  110.         DecIndx,
  111.         IncIndx : integer;
  112.         initflag: boolean;
  113.         DecAddr,
  114.         IncAddr : PObj
  115.     end;
  116.  
  117.     PGroupBox = ^TGroupBox;
  118.     TGroupBox = object(TControl)
  119.         public
  120.         constructor Init(AParent: PDialog; AnIndx: integer; ATitle,Hlp: string);
  121.         destructor Done; virtual;
  122.         procedure SetText(ATextString: string); virtual;
  123.         function GetText: string; virtual;
  124.         private
  125.         Title    : PString;
  126.         UsrBlk   : USERBLK;
  127.         oldflags : word;
  128.         oldobspec: longint
  129.     end;
  130.  
  131.     PCheckBox = ^TCheckBox;
  132.     TCheckBox = object(TButton)
  133.         public
  134.         constructor Init(AParent: PDialog; AnIndx: integer; UserDef: boolean; Hlp: string);
  135.         function Install: boolean; virtual;
  136.         function Transfer(DataPtr: pointer; TransferFlag: word): word; virtual;
  137.         procedure SetCheck(CheckFlag: integer); virtual;
  138.         function GetCheck: integer; virtual;
  139.         procedure Check; virtual;
  140.         procedure Uncheck; virtual;
  141.         procedure Toggle; virtual;
  142.     end;
  143.  
  144.     PTriState = ^TTriState;
  145.     TTriState = object(TCheckBox)
  146.         public
  147.         constructor Init(AParent: PDialog; AnIndx: integer; Hlp: string);
  148.         procedure Gray; virtual;
  149.     end;
  150.  
  151.     PRadioButton = ^TRadioButton;
  152.     TRadioButton = object(TCheckBox)
  153.         public
  154.         constructor Init(AParent: PDialog; AnIndx: integer; UserDef: boolean; Hlp: string);
  155.         procedure SetState(StateFlag: integer); virtual;
  156.         function Install: boolean; virtual;
  157.     end;
  158.  
  159.     PListBox     = ^TListBox;
  160.     TListBox     = object(TControl)
  161.         { ... }
  162.     end;
  163.  
  164.     PComboBox    = ^TComboBox;
  165.     TComboBox    = object(TControl)
  166.         { ... }
  167.     end;
  168.  
  169.  
  170.  
  171. implementation
  172.  
  173. uses
  174.  
  175.     OProcs;
  176.  
  177. const
  178.  
  179.     cbUnchecked = $1000;
  180.     cbChecked   = $2000;
  181.     cbGrayed    = $3000;
  182.     cbFlags     = cbUnchecked or cbChecked or cbGrayed;
  183.     cbType      = $4000;
  184.     cbAll       = not(cbFlags or cbType);
  185.     UDCOL       = Blue;
  186.     HOTCOL      = Red;
  187.  
  188.  
  189. function DrawGroupBox(dummy1,dummy2: pointer; parm: PARMBLKPtr): word; forward;
  190. function DrawCheckBox(dummy1,dummy2: pointer; parm: PARMBLKPtr): word; forward;
  191. function DrawRadioButton(dummy1,dummy2: pointer; parm: PARMBLKPtr): word; forward;
  192.  
  193.  
  194. { *** Objekt TSCROLLBAR *** }
  195.  
  196. constructor TScrollBar.Init(AParent: PDialog; SIndx,DIndx,IIndx: integer; TheSize,TheRange: longint; Hlp: string);
  197.  
  198.     begin
  199.         if not(inherited Init(AParent,SIndx,Hlp)) then fail;
  200.         Style:=cs_ScrollBar;
  201.         ID:=id_NoExit;
  202.         initflag:=true;
  203.         DecIndx:=DIndx;
  204.         IncIndx:=IIndx;
  205.         DecAddr:=@Parent^.DlgTree^[DecIndx];
  206.         IncAddr:=@Parent^.DlgTree^[IncIndx];
  207.         if (DecAddr=nil) or (IncAddr=nil) then
  208.             begin
  209.                 inherited Done;
  210.                 fail
  211.             end;
  212.         if ((DecAddr^.ob_type and $ff)<>G_BOXCHAR) or ((IncAddr^.ob_type and $ff)<>G_BOXCHAR) or
  213.            ((ObjAddr^.ob_type and $ff)<>G_BOX) or (ObjAddr^.ob_head=-1) then
  214.             begin
  215.                 inherited Done;
  216.                 fail
  217.             end;
  218.         if ObjAddr^.ob_height>ObjAddr^.ob_width then
  219.             begin
  220.                 DecAddr^.ob_spec.index:=(DecAddr^.ob_spec.index and $00ffffff) or ($01000000);
  221.                 IncAddr^.ob_spec.index:=(IncAddr^.ob_spec.index and $00ffffff) or ($02000000);
  222.                 Parent^.DlgTree^[ObjAddr^.ob_head].ob_width:=ObjAddr^.ob_width;
  223.                 Parent^.DlgTree^[ObjAddr^.ob_head].ob_x:=0;
  224.                 Style:=Style or sbs_Vert;
  225.                 IsHorizontal:=false
  226.             end
  227.         else
  228.             begin
  229.                 DecAddr^.ob_spec.index:=(DecAddr^.ob_spec.index and $00ffffff) or ($04000000);
  230.                 IncAddr^.ob_spec.index:=(IncAddr^.ob_spec.index and $00ffffff) or ($03000000);
  231.                 Parent^.DlgTree^[ObjAddr^.ob_head].ob_height:=ObjAddr^.ob_height;
  232.                 Parent^.DlgTree^[ObjAddr^.ob_head].ob_y:=0;
  233.                 Style:=Style or sbs_Horz;
  234.                 IsHorizontal:=true
  235.             end;
  236.         DecAddr^.ob_flags:=(DecAddr^.ob_flags and not(SELECTABLE or DEFAULT or F_EXIT or EDITABLE or RBUTTON)) or TOUCHEXIT;
  237.         IncAddr^.ob_flags:=(IncAddr^.ob_flags and not(SELECTABLE or DEFAULT or F_EXIT or EDITABLE or RBUTTON)) or TOUCHEXIT;
  238.         ObjAddr^.ob_flags:=(ObjAddr^.ob_flags and not(SELECTABLE or DEFAULT or F_EXIT or EDITABLE or RBUTTON)) or TOUCHEXIT;
  239.         Parent^.DlgTree^[ObjAddr^.ob_head].ob_flags:=(Parent^.DlgTree^[ObjAddr^.ob_head].ob_flags and not(SELECTABLE or DEFAULT or F_EXIT or EDITABLE or RBUTTON)) or TOUCHEXIT;
  240.         Size:=Max(1,TheSize);
  241.         PageMagnitude:=Size;
  242.         LineMagnitude:=1;
  243.         SPos:=-1;
  244.         Range:=Max(1,TheRange-1)+2;
  245.         SetRange(0,Range-2);
  246.         initflag:=false
  247.     end;
  248.  
  249.  
  250. function TScrollBar.TestIndex(AnIndx: integer): boolean;
  251.  
  252.     begin
  253.         TestIndex:=((AnIndx=ObjIndx) or (AnIndx=DecIndx) or (AnIndx=IncIndx) or
  254.                     (AnIndx=ObjAddr^.ob_head))
  255.     end;
  256.  
  257.  
  258. function TScrollBar.Transfer(DataPtr: pointer; TransferFlag: word): word;
  259.  
  260.     begin
  261.         case TransferFlag of
  262.             tf_SetData: with PScrollBarTransferRec(DataPtr)^ do
  263.                                         begin
  264.                                             SetRange(LowValue,HighValue);
  265.                                             SetPosition(Position)
  266.                                         end;
  267.             tf_GetData: with PScrollBarTransferRec(DataPtr)^ do
  268.                                         begin
  269.                                             LowValue:=lowval;
  270.                                             HighValue:=highval;
  271.                                             Position:=GetPosition
  272.                                         end
  273.         end;
  274.         Transfer:=sizeof(TScrollBarTransferRec)
  275.     end;
  276.  
  277.  
  278. procedure TScrollBar.Changed(AnIndx: integer; DblClick: boolean);
  279.     var sp,dif           : longint;
  280.         mx,my,ox,oy,px,py: integer;
  281.         less             : boolean;
  282.  
  283.     begin
  284.         sp:=SPos;
  285.         if AnIndx=DecIndx then
  286.             begin
  287.                 if DblClick then sp:=0
  288.                 else
  289.                     dec(sp,LineMagnitude)
  290.             end
  291.         else
  292.             if AnIndx=IncIndx then
  293.                 begin
  294.                     if DblClick then sp:=Range
  295.                     else
  296.                         inc(sp,LineMagnitude)
  297.                 end
  298.             else
  299.                 if AnIndx=ObjIndx then
  300.                     begin
  301.                         graf_mkstate(mx,my,ox,ox);
  302.                         objc_offset(Parent^.DlgTree,ObjAddr^.ob_head,ox,oy);
  303.                         if IsHorizontal then less:=(mx<ox)
  304.                         else
  305.                             less:=(my<oy);
  306.                         if less then
  307.                             begin
  308.                                 if DblClick then sp:=0
  309.                                 else
  310.                                     dec(sp,PageMagnitude)
  311.                             end
  312.                         else
  313.                             begin
  314.                                 if DblClick then sp:=Range
  315.                                 else
  316.                                     inc(sp,PageMagnitude)
  317.                             end
  318.                     end
  319.                 else
  320.                     begin
  321.                         objc_offset(Parent^.DlgTree,ObjAddr^.ob_head,ox,oy);
  322.                         objc_offset(Parent^.DlgTree,ObjIndx,px,py);
  323.                         wind_update(BEG_UPDATE);
  324.                         graf_dragbox(Parent^.DlgTree^[ObjAddr^.ob_head].ob_width,Parent^.DlgTree^[ObjAddr^.ob_head].ob_height,ox,oy,px,py,ObjAddr^.ob_width,ObjAddr^.ob_height,mx,my);
  325.                         if (mx<>ox) or (my<>oy) then
  326.                             begin
  327.                                 dif:=Max(0,Range-Size);
  328.                                 if IsHorizontal then
  329.                                     begin
  330.                                         ox:=ObjAddr^.ob_width-Parent^.DlgTree^[ObjAddr^.ob_head].ob_width;
  331.                                         if ox<1 then sp:=0
  332.                                         else
  333.                                             sp:=((mx-px)*dif) div ox;
  334.                                     end
  335.                                 else
  336.                                     begin
  337.                                         oy:=ObjAddr^.ob_height-Parent^.DlgTree^[ObjAddr^.ob_head].ob_height;
  338.                                         if oy<1 then sp:=0
  339.                                         else
  340.                                             sp:=((my-py)*dif) div oy;
  341.                                     end
  342.                             end;
  343.                         wind_update(END_UPDATE)
  344.                     end;
  345.         SetPosition(sp+lowval)
  346.     end;
  347.  
  348.  
  349. procedure TScrollBar.Work;
  350.  
  351.     begin
  352.     end;
  353.  
  354.  
  355. procedure TScrollBar.SetPosition(ThumbPos: longint);
  356.     var dif: longint;
  357.  
  358.     begin
  359.         dec(ThumbPos,lowval);
  360.         dif:=Range-Size;
  361.         if ThumbPos+Size>Range then ThumbPos:=dif;
  362.         if ThumbPos<0 then ThumbPos:=0;
  363.         if SPos<>ThumbPos then
  364.             begin
  365.                 SPos:=ThumbPos;
  366.                 if dif<1 then dif:=1;
  367.                 if IsHorizontal then
  368.                     Parent^.DlgTree^[ObjAddr^.ob_head].ob_x:=((ObjAddr^.ob_width-Parent^.DlgTree^[ObjAddr^.ob_head].ob_width)*SPos) div dif
  369.                 else
  370.                     Parent^.DlgTree^[ObjAddr^.ob_head].ob_y:=((ObjAddr^.ob_height-Parent^.DlgTree^[ObjAddr^.ob_head].ob_height)*SPos) div dif;
  371.                 if not(initflag) then
  372.                     begin
  373.                         Paint;
  374.                         Work
  375.                     end
  376.             end
  377.     end;
  378.  
  379.  
  380. function TScrollBar.GetPosition: longint;
  381.  
  382.     begin
  383.         GetPosition:=SPos+lowval
  384.     end;
  385.  
  386.  
  387. function TScrollBar.DeltaPos(Delta: longint): longint;
  388.  
  389.     begin
  390.         if Delta<>0 then SetPosition(SPos+lowval+Delta);
  391.         DeltaPos:=SPos+lowval
  392.     end;
  393.  
  394.  
  395. procedure TScrollBar.SetRange(LoVal,HiVal: longint);
  396.     var sp,s,TheRange: longint;
  397.  
  398.     begin
  399.         TheRange:=HiVal+1-LoVal;
  400.         if TheRange<1 then
  401.             begin
  402.                 HiVal:=LoVal+1;
  403.                 TheRange:=1
  404.             end;
  405.         lowval:=LoVal;
  406.         highval:=HiVal;
  407.         if Range<>TheRange then
  408.             begin
  409.                 Range:=TheRange;
  410.                 if IsHorizontal then
  411.                     begin
  412.                         s:=(ObjAddr^.ob_width*Size) div Range;
  413.                         if s>ObjAddr^.ob_width then s:=ObjAddr^.ob_width;
  414.                         if s<GetSBoxMin then s:=GetSBoxMin;
  415.                         Parent^.DlgTree^[ObjAddr^.ob_head].ob_width:=s
  416.                     end
  417.                 else
  418.                     begin
  419.                         s:=(ObjAddr^.ob_height*Size) div Range;
  420.                         if s>ObjAddr^.ob_height then s:=ObjAddr^.ob_height;
  421.                         if s<GetSBoxMin then s:=GetSBoxMin;
  422.                         Parent^.DlgTree^[ObjAddr^.ob_head].ob_height:=s
  423.                     end;
  424.                 sp:=SPos;
  425.                 SetPosition(SPos+lowval);
  426.                 if sp=SPos then
  427.                     if not(initflag) then
  428.                         begin
  429.                             Paint;
  430.                             Work
  431.                         end
  432.             end
  433.     end;
  434.  
  435.  
  436. function TScrollBar.GetRange(var LoVal,HiVal: longint): longint;
  437.  
  438.     begin
  439.         LoVal:=lowval;
  440.         HiVal:=highval;
  441.         GetRange:=Range+1
  442.     end;
  443.  
  444.  
  445. function TScrollBar.GetSBoxMin: integer;
  446.  
  447.     begin
  448.         GetSBoxMin:=8
  449.     end;
  450.  
  451. { *** TSCROLLBAR *** }
  452.  
  453.  
  454.  
  455. { *** Objekt TGROUPBOX *** }
  456.  
  457. constructor TGroupBox.Init(AParent: PDialog; AnIndx: integer; ATitle,Hlp: string);
  458.  
  459.     begin
  460.         if not(inherited Init(AParent,AnIndx,Hlp)) then fail;
  461.         Style:=cs_GroupBox;
  462.         Title:=NewStr(ATitle);
  463.         if ((ObjAddr^.ob_type and $ff)=G_BOX) and (Title<>nil) then
  464.             with ObjAddr^ do
  465.                 begin
  466.                     oldflags:=ob_flags;
  467.                     oldobspec:=ob_spec.index;
  468.                     UsrBlk.ub_parm:=longint(Title);
  469.                     UsrBlk.ub_code:=@DrawGroupBox;
  470.                     ob_flags:=ob_flags and not(RBUTTON or EDITABLE or SELECTABLE or DEFAULT or F_EXIT or TOUCHEXIT);
  471.                     ob_type:=G_USERDEF;
  472.                     ob_spec.user_blk:=@UsrBlk
  473.                 end
  474.         else
  475.             begin
  476.                 DisposeStr(Title);
  477.                 inherited Done;
  478.                 fail
  479.             end
  480.     end;
  481.  
  482.  
  483. destructor TGroupBox.Done;
  484.  
  485.     begin
  486.         with ObjAddr^ do
  487.             begin
  488.                 ob_spec.index:=oldobspec;
  489.                 ob_type:=G_BOX;
  490.                 ob_flags:=oldflags
  491.             end;
  492.         DisposeStr(Title);
  493.         inherited Done
  494.     end;
  495.  
  496.  
  497. procedure TGroupBox.SetText(ATextString: string);
  498.     var nt: PString;
  499.  
  500.     begin
  501.         nt:=NewStr(ATextString);
  502.         if nt<>nil then
  503.             begin
  504.                 DisposeStr(Title);
  505.                 Title:=nt;
  506.                 UsrBlk.ub_parm:=longint(Title);
  507.                 Paint
  508.             end
  509.     end;
  510.  
  511.  
  512. function TGroupBox.GetText: string;
  513.  
  514.     begin
  515.         if Title<>nil then GetText:=Title^ else GetText:=''
  516.     end;
  517.  
  518. { *** TGROUPBOX ***}
  519.  
  520.  
  521.  
  522. { *** Objekt TCHECKBOX *** }
  523.  
  524. constructor TCheckBox.Init(AParent: PDialog; AnIndx: integer; UserDef: boolean; Hlp: string);
  525.  
  526.     begin
  527.         if not(inherited Init(AParent,AnIndx,id_No,UserDef,Hlp)) then fail;
  528.         EnableTransfer;
  529.         Style:=cs_CheckBox;
  530.         if UsrDef then
  531.             with ObjAddr^ do
  532.                 begin
  533.                     ob_type:=ob_type and cbAll;
  534.                     if bTst(ob_state,SELECTED) then ob_type:=ob_type or cbChecked
  535.                     else
  536.                         ob_type:=ob_type or cbUnchecked
  537.                 end
  538.     end;
  539.  
  540.  
  541. function TCheckBox.Install: boolean;
  542.  
  543.     begin
  544.         with ObjAddr^ do
  545.             if (ob_type and $ff)=G_BUTTON then
  546.                 begin
  547.                     UsrBlk.ub_parm:=ob_spec.index;
  548.                     UsrBlk.ub_code:=@DrawCheckBox;
  549.                     ob_flags:=(ob_flags and not(RBUTTON or EDITABLE)) or SELECTABLE;
  550.                     ob_state:=ob_state and not(CHECKED or OUTLINED or SHADOWED);
  551.                     ob_type:=G_USERDEF;
  552.                     ob_spec.user_blk:=@UsrBlk
  553.                 end
  554.             else
  555.                 UsrDef:=false;
  556.         Install:=true
  557.     end;
  558.  
  559.  
  560. function TCheckBox.Transfer(DataPtr: pointer; TransferFlag: word): word;
  561.  
  562.     begin
  563.         case TransferFlag of
  564.             tf_SetData: SetCheck(PWord(DataPtr)^);
  565.             tf_GetData: PWord(DataPtr)^:=GetCheck
  566.         end;
  567.         Transfer:=2
  568.     end;
  569.  
  570.  
  571. procedure TCheckBox.SetCheck(CheckFlag: integer);
  572.  
  573.     begin
  574.         if CheckFlag=bf_Grayed then
  575.             if not(bTst(Style,cs_3State)) then CheckFlag:=bf_Unchecked;
  576.         if GetCheck<>CheckFlag then
  577.             begin
  578.                 with ObjAddr^ do
  579.                     if UsrDef then
  580.                         case CheckFlag of
  581.                             bf_Unchecked: begin
  582.                                                             ob_type:=(ob_type and not(cbFlags)) or cbUnchecked;
  583.                                                             ob_state:=ob_state and not(SELECTED)
  584.                                                         end;
  585.                             bf_Checked:   begin
  586.                                                             ob_type:=(ob_type and not(cbFlags)) or cbChecked;
  587.                                                             ob_state:=ob_state or SELECTED
  588.                                                         end;
  589.                             bf_Grayed:    ob_type:=ob_type or cbGrayed
  590.                         end
  591.                     else
  592.                         case CheckFlag of
  593.                             bf_Unchecked: ob_state:=ob_state and not(SELECTED)
  594.                         else
  595.                             ob_state:=ob_state or SELECTED
  596.                         end;
  597.                 Paint
  598.             end
  599.     end;
  600.  
  601.  
  602. function TCheckBox.GetCheck: integer;
  603.  
  604.     begin
  605.         with ObjAddr^ do
  606.             if UsrDef then
  607.                 case (ob_type and cbFlags) of
  608.                     cbUnChecked: GetCheck:=bf_Unchecked;
  609.                     cbChecked  : GetCheck:=bf_Checked;
  610.                     cbGrayed   : GetCheck:=bf_Grayed
  611.                 else
  612.                     GetCheck:=bf_Unchecked
  613.                 end
  614.             else
  615.                 begin
  616.                     if bTst(ob_state,SELECTED) then GetCheck:=bf_Checked
  617.                     else
  618.                         GetCheck:=bf_Unchecked
  619.                 end
  620.     end;
  621.  
  622.  
  623. procedure TCheckBox.Check;
  624.  
  625.     begin
  626.         SetCheck(bf_Checked)
  627.     end;
  628.  
  629.  
  630. procedure TCheckBox.Uncheck;
  631.  
  632.     begin
  633.         SetCheck(bf_Unchecked)
  634.     end;
  635.  
  636.  
  637. procedure TCheckBox.Toggle;
  638.  
  639.     begin
  640.         case GetCheck of
  641.             bf_Unchecked: SetCheck(bf_Checked);
  642.             bf_Checked:   SetCheck(bf_Grayed);
  643.             bf_Grayed:    SetCheck(bf_Unchecked)
  644.         end
  645.     end;
  646.  
  647. { *** TCHECKBOX *** }
  648.  
  649.  
  650.  
  651. { *** Objekt TTRISTATE *** }
  652.  
  653. constructor TTriState.Init(AParent: PDialog; AnIndx: integer; Hlp: string);
  654.  
  655.     begin
  656.         if not(TCheckBox.Init(AParent,AnIndx,true,Hlp)) then fail;
  657.         Style:=cs_3State;
  658.         with ObjAddr^ do ob_type:=ob_type or cbType
  659.     end;
  660.  
  661.  
  662. procedure TTriState.Gray;
  663.  
  664.     begin
  665.         SetCheck(bf_Grayed)
  666.     end;
  667.  
  668. { *** TTRISTATE ***}
  669.  
  670.  
  671.  
  672. { *** Objekt TRADIOBUTTON *** }
  673.  
  674. constructor TRadioButton.Init(AParent: PDialog; AnIndx: integer; UserDef: boolean; Hlp: string);
  675.  
  676.     begin
  677.         if not(inherited Init(AParent,AnIndx,UserDef,Hlp)) then fail;
  678.         Style:=cs_RadioButton
  679.     end;
  680.  
  681.  
  682. procedure TRadioButton.SetState(StateFlag: integer);
  683.  
  684.     begin
  685.         if GetState<>StateFlag then
  686.             begin
  687.                 if StateFlag=bf_Disabled then Uncheck;
  688.                 inherited SetState(StateFlag)
  689.             end
  690.     end;
  691.  
  692.  
  693. function TRadioButton.Install: boolean;
  694.  
  695.     begin
  696.         with ObjAddr^ do
  697.             if (ob_type and $ff)=G_BUTTON then
  698.                 begin
  699.                     UsrBlk.ub_parm:=ob_spec.index;
  700.                     UsrBlk.ub_code:=@DrawRadioButton;
  701.                     ob_flags:=(ob_flags and not(EDITABLE)) or RBUTTON or SELECTABLE;
  702.                     ob_state:=ob_state and not(CROSSED or CHECKED or OUTLINED or SHADOWED);
  703.                     ob_type:=G_USERDEF;
  704.                     ob_spec.user_blk:=@UsrBlk
  705.                 end
  706.             else
  707.                 UsrDef:=false;
  708.         Install:=true
  709.     end;
  710.  
  711. { *** TRADIOBUTTON *** }
  712.  
  713.  
  714.  
  715. function DrawGroupBox(dummy1,dummy2: pointer; parm: PARMBLKPtr): word;
  716.     var clip: ARRAY_4;
  717.  
  718.     begin
  719.         InitVWrk;
  720.         with parm^ do
  721.             begin
  722.                 clip[0]:=pb_xc;
  723.                 clip[1]:=pb_yc;
  724.                 clip[2]:=pb_xc+pb_wc-1;
  725.                 clip[3]:=pb_yc+pb_hc-1;
  726.                 vs_clip(Application^.vdiHandle,CLIP_ON,clip);
  727.                 clip[0]:=pb_x;
  728.                 clip[1]:=pb_y;
  729.                 clip[2]:=pb_x+pb_w-1;
  730.                 clip[3]:=pb_y+pb_h-1
  731.             end;
  732.         with Application^ do
  733.             begin
  734.                 vsf_interior(vdiHandle,FIS_SOLID);
  735.                 vsf_color(vdiHandle,SysInfo.BGDefCol);
  736.                 v_bar(vdiHandle,clip);
  737.                 vsf_interior(vdiHandle,FIS_HOLLOW);
  738.                 vsf_color(vdiHandle,Black);
  739.                 vswr_mode(vdiHandle,MD_TRANS);
  740.                 v_bar(vdiHandle,clip);
  741.                 if length(PString(parm^.pb_parm)^)>0 then
  742.                     begin
  743.                         gem.vswr_mode(vdiHandle,MD_ERASE);
  744.                         gem.vst_color(vdiHandle,SysInfo.BGDefCol);
  745.                         v_gtext(vdiHandle,parm^.pb_x+Attr.charSWidth,parm^.pb_y+(SysInfo.SFHeight shr 1),' '+PString(parm^.pb_parm)^+' ');
  746.                         gem.vswr_mode(vdiHandle,MD_TRANS);
  747.                         v_gtext(vdiHandle,parm^.pb_x+Attr.charSWidth,parm^.pb_y+(SysInfo.SFHeight shr 1),' '+PString(parm^.pb_parm)^+' ');
  748.                         gem.vst_color(vdiHandle,Black);
  749.                         v_gtext(vdiHandle,parm^.pb_x+Attr.charSWidth,parm^.pb_y+(SysInfo.SFHeight shr 1),' '+PString(parm^.pb_parm)^+' ')
  750.                     end
  751.             end;
  752.         RestoreVWrk;
  753.         DrawGroupBox:=NORMAL
  754.     end;
  755.  
  756.  
  757. function DrawCheckBox(dummy1,dummy2: pointer; parm: PARMBLKPtr): word;
  758.     var clip            : ARRAY_4;
  759.         tx,ty,scpos,stat: integer;
  760.         q               : word;
  761.         btn             : string[40];
  762.  
  763.     begin
  764.         InitVWrk;
  765.         with parm^ do
  766.             begin
  767.                 clip[0]:=pb_xc;
  768.                 clip[1]:=pb_yc;
  769.                 clip[2]:=pb_xc+pb_wc-1;
  770.                 clip[3]:=pb_yc+pb_hc-1;
  771.                 vs_clip(Application^.vdiHandle,CLIP_ON,clip);
  772.                 clip[0]:=pb_x+1;
  773.                 clip[1]:=pb_y+1;
  774.                 clip[2]:=clip[0]+13;
  775.                 clip[3]:=clip[1]+13;
  776.                 case (pb_tree^[pb_obj].ob_type and cbFlags) of
  777.                     cbChecked:   stat:=bf_Checked;
  778.                     cbGrayed:    stat:=bf_Grayed
  779.                 else
  780.                     stat:=bf_Unchecked
  781.                 end;
  782.                 if pr_currstate<>pr_prevstate then
  783.                     begin
  784.                         inc(stat);
  785.                         if bTst(pb_tree^[pb_obj].ob_type,cbType) then q:=3 else q:=2;
  786.                         if stat>q then stat:=1;
  787.                         case stat of
  788.                             bf_Checked:   q:=cbChecked;
  789.                             bf_Grayed:    q:=cbGrayed
  790.                         else
  791.                             q:=cbUnchecked
  792.                         end;
  793.                         pb_tree^[pb_obj].ob_type:=(pb_tree^[pb_obj].ob_type and not(cbFlags)) or q
  794.                     end;
  795.                 if (stat<>bf_Unchecked) or bTst(pr_currstate,CROSSED) then for q:=0 to 3 do inc(clip[q])
  796.             end;
  797.         with Application^ do
  798.             begin
  799.                 if stat=bf_Grayed then
  800.                     begin
  801.                         if Attr.Colors>=LWhite then
  802.                             begin
  803.                                 gem.vsf_interior(vdiHandle,FIS_SOLID);
  804.                                 gem.vsf_color(vdiHandle,LWhite)
  805.                             end
  806.                         else
  807.                             begin
  808.                                 gem.vsf_interior(vdiHandle,FIS_PATTERN);
  809.                                 gem.vsf_style(vdiHandle,1)
  810.                             end
  811.                     end;
  812.                 v_bar(vdiHandle,clip);
  813.                 if stat<>bf_Unchecked then
  814.                     begin
  815.                         pxya[0]:=clip[0]-1;
  816.                         pxya[1]:=clip[3]-1;
  817.                         pxya[2]:=clip[0]-1;
  818.                         pxya[3]:=clip[1]-1;
  819.                         pxya[4]:=clip[2]-1;
  820.                         pxya[5]:=clip[1]-1;
  821.                         gem.vsl_color(vdiHandle,SysInfo.BGDefCol);
  822.                         v_pline(vdiHandle,3,pxya);
  823.                         if stat=bf_Checked then
  824.                             begin
  825.                                 gem.vsl_color(vdiHandle,LBlack);
  826.                                 if bTst(parm^.pr_currstate,CROSSED) then
  827.                                     begin
  828.                                         pxya[0]:=clip[0]+1;
  829.                                         pxya[1]:=clip[1]+1;
  830.                                         pxya[2]:=clip[2]-1;
  831.                                         pxya[3]:=clip[3]-1;
  832.                                         v_pline(vdiHandle,2,pxya);
  833.                                         pxya[0]:=clip[0]+1;
  834.                                         pxya[1]:=clip[3]-1;
  835.                                         pxya[2]:=clip[2]-1;
  836.                                         pxya[3]:=clip[1]+1;
  837.                                         v_pline(vdiHandle,2,pxya)
  838.                                     end
  839.                                 else
  840.                                     begin
  841.                                         pxya[0]:=clip[0]+1;
  842.                                         pxya[1]:=clip[3]-1;
  843.                                         pxya[2]:=clip[0]+1;
  844.                                         pxya[3]:=clip[1]+1;
  845.                                         pxya[4]:=clip[2]-1;
  846.                                         pxya[5]:=clip[1]+1;
  847.                                         v_pline(vdiHandle,3,pxya);
  848.                                         gem.vsf_interior(vdiHandle,FIS_SOLID);
  849.                                         gem.vsf_color(vdiHandle,UDCOL);
  850.                                         gem.vsl_color(vdiHandle,UDCOL);
  851.                                         if bTst(parm^.pr_currstate,DISABLED) then
  852.                                             if Attr.Colors>=LWhite then
  853.                                                 begin
  854.                                                     gem.vsf_color(vdiHandle,LWhite);
  855.                                                     gem.vsl_color(vdiHandle,LWhite)
  856.                                                 end;
  857.                                         pxya[0]:=clip[0]+5;
  858.                                         pxya[1]:=clip[1]+7;
  859.                                         pxya[2]:=clip[0]+4;
  860.                                         pxya[3]:=clip[1]+8;
  861.                                         pxya[4]:=clip[0]+4;
  862.                                         pxya[5]:=clip[1]+11;
  863.                                         pxya[6]:=clip[0]+5;
  864.                                         pxya[7]:=clip[1]+11;
  865.                                         pxya[8]:=clip[0]+11;
  866.                                         pxya[9]:=clip[1]+5;
  867.                                         pxya[10]:=clip[0]+10;
  868.                                         pxya[11]:=clip[1]+5;
  869.                                         pxya[12]:=clip[0]+5;
  870.                                         pxya[13]:=clip[1]+10;
  871.                                         pxya[14]:=clip[0]+5;
  872.                                         pxya[15]:=clip[1]+7;
  873.                                         v_fillarea(vdiHandle,8,pxya)
  874.                                     end
  875.                             end
  876.                         else
  877.                             if Attr.Colors>=LWhite then
  878.                                 begin
  879.                                     pxya[0]:=clip[0];
  880.                                     pxya[1]:=clip[1];
  881.                                     pxya[2]:=clip[2];
  882.                                     pxya[3]:=clip[1];
  883.                                     pxya[4]:=clip[2];
  884.                                     pxya[5]:=clip[3];
  885.                                     pxya[6]:=clip[0];
  886.                                     pxya[7]:=clip[3];
  887.                                     pxya[8]:=clip[0];
  888.                                     pxya[9]:=clip[1];
  889.                                     gem.vsl_color(vdiHandle,Black);
  890.                                     v_pline(vdiHandle,5,pxya)
  891.                                 end
  892.                     end
  893.                 else
  894.                     if not(bTst(parm^.pr_currstate,CROSSED)) then
  895.                         begin
  896.                             pxya[0]:=clip[0]+1;
  897.                             pxya[1]:=clip[3]+1;
  898.                             pxya[2]:=clip[2]+1;
  899.                             pxya[3]:=clip[3]+1;
  900.                             pxya[4]:=clip[2]+1;
  901.                             pxya[5]:=clip[1]+1;
  902.                             gem.vsl_color(vdiHandle,LBlack);
  903.                             v_pline(vdiHandle,3,pxya)
  904.                         end;
  905.                 tx:=parm^.pb_x+14+Attr.charSWidth;
  906.                 ty:=parm^.pb_y+SysInfo.SFHeight+1;
  907.                 btn:=StrLPas(PChar(parm^.pb_parm),40);
  908.                 while btn[length(btn)]=' ' do btn[0]:=chr(ord(btn[0])-1);
  909.                 scpos:=pos('&',btn);
  910.                 if scpos>0 then
  911.                     begin
  912.                         for q:=scpos to length(btn)-1 do btn[q]:=btn[q+1];
  913.                         btn[0]:=chr(ord(btn[0])-1)
  914.                     end;
  915.                 gem.vswr_mode(vdiHandle,MD_ERASE);
  916.                 gem.vst_color(vdiHandle,SysInfo.BGDefCol);
  917.                 v_gtext(vdiHandle,tx,ty,btn);
  918.                 gem.vswr_mode(vdiHandle,MD_TRANS);
  919.                 v_gtext(vdiHandle,tx,ty,btn);
  920.                 if bTst(parm^.pr_currstate,DISABLED) then gem.vst_effects(vdiHandle,TF_LIGHTENED);
  921.                 gem.vst_color(vdiHandle,Black);
  922.                 v_gtext(vdiHandle,tx,ty,btn);
  923.                 if scpos>0 then
  924.                     begin
  925.                         if bTst(parm^.pr_currstate,DISABLED) then gem.vst_effects(vdiHandle,TF_UNDERLINED or TF_LIGHTENED)
  926.                         else
  927.                             begin
  928.                                 gem.vst_effects(vdiHandle,TF_UNDERLINED);
  929.                                 gem.vst_color(vdiHandle,HOTCOL)
  930.                             end;
  931.                         v_gtext(vdiHandle,tx+(scpos-1)*Attr.charSWidth,ty,' ')
  932.                     end;
  933.                 RestoreVWrk
  934.             end;
  935.         DrawCheckBox:=NORMAL
  936.     end;
  937.  
  938.  
  939. function DrawRadioButton(dummy1,dummy2: pointer; parm: PARMBLKPtr): word;
  940.     var clip            : ARRAY_4;
  941.         stat,tx,ty,scpos: integer;
  942.         q               : word;
  943.         btn             : string[40];
  944.  
  945.     begin
  946.         with parm^ do
  947.             begin
  948.                 clip[0]:=pb_xc;
  949.                 clip[1]:=pb_yc;
  950.                 clip[2]:=pb_xc+pb_wc-1;
  951.                 clip[3]:=pb_yc+pb_hc-1;
  952.                 if (pb_tree^[pb_obj].ob_type and cbFlags)=cbChecked then stat:=bf_Checked
  953.                 else
  954.                     stat:=bf_Unchecked;
  955.                 if pr_currstate<>pr_prevstate then
  956.                     begin
  957.                         stat:=stat xor 3;
  958.                         if stat=bf_Checked then q:=cbChecked
  959.                         else
  960.                             q:=cbUnchecked;
  961.                         pb_tree^[pb_obj].ob_type:=(pb_tree^[pb_obj].ob_type and not(cbFlags)) or q
  962.                     end;
  963.                 vs_clip(Application^.vdiHandle,CLIP_ON,clip);
  964.                 InitVWrk;
  965.                 pxya[0]:=pb_x+1;
  966.                 pxya[1]:=pb_y+8;
  967.                 pxya[2]:=pb_x+8;
  968.                 pxya[3]:=pb_y+15;
  969.                 pxya[4]:=pb_x+15;
  970.                 pxya[5]:=pb_y+8;
  971.                 pxya[6]:=pb_x+8;
  972.                 pxya[7]:=pb_y+1;
  973.                 pxya[8]:=pb_x+1;
  974.                 pxya[9]:=pb_y+8
  975.             end;
  976.         if stat=bf_Checked then for q:=0 to 4 do inc(pxya[q shl 1]);
  977.         with Application^ do
  978.             begin
  979.                 v_fillarea(vdiHandle,5,pxya);
  980.                 gem.vsf_perimeter(vdiHandle,PER_ON);
  981.                 if stat=bf_Checked then
  982.                     begin
  983.                         pxya[0]:=parm^.pb_x+8;
  984.                         pxya[1]:=parm^.pb_y+1;
  985.                         pxya[2]:=parm^.pb_x+1;
  986.                         pxya[3]:=parm^.pb_y+8;
  987.                         pxya[4]:=parm^.pb_x+8;
  988.                         pxya[5]:=parm^.pb_y+15;
  989.                         gem.vsl_color(vdiHandle,SysInfo.BGDefCol);
  990.                         v_pline(vdiHandle,3,pxya);
  991.                         pxya[0]:=parm^.pb_x+9;
  992.                         pxya[1]:=parm^.pb_y+2;
  993.                         pxya[2]:=parm^.pb_x+3;
  994.                         pxya[3]:=parm^.pb_y+8;
  995.                         pxya[4]:=parm^.pb_x+9;
  996.                         pxya[5]:=parm^.pb_y+14;
  997.                         gem.vsl_color(vdiHandle,LBlack);
  998.                         v_pline(vdiHandle,3,pxya);
  999.                         gem.vsf_interior(vdiHandle,FIS_SOLID);
  1000.                         gem.vsf_color(vdiHandle,UDCOL);
  1001.                         if bTst(parm^.pr_currstate,DISABLED) then
  1002.                             if Attr.Colors>=LWhite then
  1003.                                 begin
  1004.                                     gem.vsf_color(vdiHandle,LWhite);
  1005.                                     gem.vsl_color(vdiHandle,LWhite)
  1006.                                 end;
  1007.                         pxya[0]:=parm^.pb_x+7;
  1008.                         pxya[1]:=parm^.pb_y+8;
  1009.                         pxya[2]:=parm^.pb_x+9;
  1010.                         pxya[3]:=parm^.pb_y+10;
  1011.                         pxya[4]:=parm^.pb_x+11;
  1012.                         pxya[5]:=parm^.pb_y+8;
  1013.                         pxya[6]:=parm^.pb_x+9;
  1014.                         pxya[7]:=parm^.pb_y+6;
  1015.                         pxya[8]:=parm^.pb_x+7;
  1016.                         pxya[9]:=parm^.pb_y+8;
  1017.                         v_fillarea(vdiHandle,5,pxya)
  1018.                     end
  1019.                 else
  1020.                     begin
  1021.                         pxya[0]:=parm^.pb_x+9;
  1022.                         pxya[1]:=parm^.pb_y+1;
  1023.                         pxya[2]:=parm^.pb_x+16;
  1024.                         pxya[3]:=parm^.pb_y+8;
  1025.                         pxya[4]:=parm^.pb_x+9;
  1026.                         pxya[5]:=parm^.pb_y+15;
  1027.                         gem.vsl_color(vdiHandle,LBlack);
  1028.                         v_pline(vdiHandle,3,pxya)
  1029.                     end;
  1030.                 tx:=parm^.pb_x+14+Attr.charSWidth;
  1031.                 ty:=parm^.pb_y+SysInfo.SFHeight+1;
  1032.                 btn:=StrLPas(PChar(parm^.pb_parm),40);
  1033.                 while btn[length(btn)]=' ' do btn[0]:=chr(ord(btn[0])-1);
  1034.                 scpos:=pos('&',btn);
  1035.                 if scpos>0 then
  1036.                     begin
  1037.                         for q:=scpos to length(btn)-1 do btn[q]:=btn[q+1];
  1038.                         btn[0]:=chr(ord(btn[0])-1)
  1039.                     end;
  1040.                 gem.vswr_mode(vdiHandle,MD_ERASE);
  1041.                 gem.vst_color(vdiHandle,SysInfo.BGDefCol);
  1042.                 v_gtext(vdiHandle,tx,ty,btn);
  1043.                 gem.vswr_mode(vdiHandle,MD_TRANS);
  1044.                 v_gtext(vdiHandle,tx,ty,btn);
  1045.                 if bTst(parm^.pr_currstate,DISABLED) then gem.vst_effects(vdiHandle,TF_LIGHTENED);
  1046.                 gem.vst_color(vdiHandle,Black);
  1047.                 v_gtext(vdiHandle,tx,ty,btn);
  1048.                 if scpos>0 then
  1049.                     begin
  1050.                         if bTst(parm^.pr_currstate,DISABLED) then gem.vst_effects(vdiHandle,TF_UNDERLINED or TF_LIGHTENED)
  1051.                         else
  1052.                             begin
  1053.                                 gem.vst_effects(vdiHandle,TF_UNDERLINED);
  1054.                                 gem.vst_color(vdiHandle,HOTCOL)
  1055.                             end;
  1056.                         v_gtext(vdiHandle,tx+(scpos-1)*Attr.charSWidth,ty,' ')
  1057.                     end;
  1058.                 RestoreVWrk
  1059.             end;
  1060.         DrawRadioButton:=NORMAL
  1061.     end;
  1062.  
  1063. end.